import { reactive, ref, toRefs, watch } from 'vue'

export interface UseDialogOptions {
  visible?: boolean
  title?: string
  width?: string | number
  fullscreen?: boolean
  top?: string | number
  modal?: boolean
  appendToBody?: boolean
  lockScroll?: boolean
  customClass?: string
  closeOnClickModal?: boolean
  closeOnPressEscape?: boolean
  showClose?: boolean
  beforeClose?: (done: () => void) => void
  destroyOnClose?: boolean
  center?: boolean
  draggable?: boolean
}

// 表单对话框配置选项
export interface UseFormDialogOptions extends UseDialogOptions {
  form?: Record<string, any>
  validateOnSubmit?: boolean
  resetOnClose?: boolean
}

/**
 * 对话框逻辑处理Hook
 */
export function useDialog(options: UseDialogOptions = {}) {
  // 基础状态
  const state = reactive({
    visible: options.visible || false,
    title: options.title || '',
    loading: false,
    dragging: false,
    form: {} as Record<string, any>,
  })

  // 对话框引用
  const dialogRef = ref<any>(null)

  // 对话框位置 (用于拖拽)
  const position = reactive({
    x: 0,
    y: 0,
  })

  // 监听visible变化
  const onVisibleChange = options.beforeClose
    ? (val: boolean, done: () => void) => {
        if (!val && options.beforeClose) {
          options.beforeClose(done)
        } else {
          done()
        }
      }
    : undefined

  // 方法
  const methods = {
    // 打开对话框
    open(params?: Record<string, any>) {
      if (params) {
        state.form = { ...params }
      }
      state.visible = true
    },

    // 关闭对话框
    close() {
      if (options.beforeClose) {
        options.beforeClose(() => {
          state.visible = false
        })
      } else {
        state.visible = false
      }
    },

    // 设置表单数据
    setForm(form: Record<string, any>) {
      state.form = { ...form }
    },

    // 获取表单数据
    getForm() {
      return state.form
    },

    // 重置表单
    resetForm() {
      state.form = {}
    },

    // 设置标题
    setTitle(title: string) {
      state.title = title
    },

    // 设置加载状态
    setLoading(loading: boolean) {
      state.loading = loading
    },

    // 确认操作
    confirm() {
      // 可以添加表单验证逻辑
      return Promise.resolve(state.form)
    },

    // 开始拖拽
    startDrag(e: MouseEvent) {
      if (!options.draggable) return

      state.dragging = true
      const dialog = dialogRef.value?.$el?.querySelector('.el-dialog')
      if (!dialog) return

      const { clientX, clientY } = e
      const { left, top } = dialog.getBoundingClientRect()

      // 记录起始位置
      const startX = clientX
      const startY = clientY
      const startLeft = left
      const startTop = top

      const move = (e: MouseEvent) => {
        const { clientX, clientY } = e
        const offsetX = clientX - startX
        const offsetY = clientY - startY

        position.x = startLeft + offsetX
        position.y = startTop + offsetY

        dialog.style.left = `${position.x}px`
        dialog.style.top = `${position.y}px`
      }

      const end = () => {
        state.dragging = false
        document.removeEventListener('mousemove', move)
        document.removeEventListener('mouseup', end)
      }

      document.addEventListener('mousemove', move)
      document.addEventListener('mouseup', end)
    },

    // 居中对话框
    centerDialog() {
      const dialog = dialogRef.value?.$el?.querySelector('.el-dialog')
      if (!dialog) return

      dialog.style.left = '50%'
      dialog.style.top = '50%'
      dialog.style.transform = 'translate(-50%, -50%)'
      position.x = 0
      position.y = 0
    },
  }

  // 监听visible变化
  watch(
    () => state.visible,
    (val) => {
      if (val && options.draggable) {
        // 延迟执行，确保DOM已更新
        setTimeout(() => {
          methods.centerDialog()
        }, 100)
      }
    }
  )

  return {
    // 暴露状态
    ...toRefs(state),
    position,
    dialogRef,

    // 暴露方法
    ...methods,
    onVisibleChange,
  }
}

/**
 * 表单对话框逻辑处理Hook
 * @param options 配置选项
 */
export function useFormDialog(options: UseFormDialogOptions = {}) {
  // 默认配置
  const defaultOptions = {
    visible: false,
    title: '',
    width: '50%',
    fullscreen: false,
    draggable: false,
    form: {},
    validateOnSubmit: true,
    resetOnClose: true,
  }

  // 合并配置
  const mergedOptions = { ...defaultOptions, ...options }

  // 内部状态
  const formState = reactive({
    // 表单提交状态
    submitting: false,
    // 表单验证状态
    validating: false,
    // 表单是否被修改过
    dirty: false,
    // 表单是否验证通过
    valid: false,
  })

  // 使用基础对话框
  const dialog = useDialog({
    visible: mergedOptions.visible,
    title: mergedOptions.title,
    width: mergedOptions.width,
    fullscreen: mergedOptions.fullscreen,
    draggable: mergedOptions.draggable,
    beforeClose: mergedOptions.beforeClose,
  })

  // 表单相关
  const form = ref(mergedOptions.form ? { ...mergedOptions.form } : {})
  const formRef = ref<any>(null)
  const formLoading = ref(false)
  const submitLoading = ref(false)

  // 记录初始表单数据，用于重置
  const initialFormData = ref({ ...mergedOptions.form })

  // 验证表单
  const validate = () => {
    return new Promise((resolve, reject) => {
      if (!formRef.value) {
        resolve(true)
        return
      }

      formState.validating = true
      formRef.value.validate((valid: boolean, fields: any) => {
        formState.valid = valid
        formState.validating = false

        if (valid) {
          resolve(true)
        } else {
          reject(fields)
          resolve(false)
        }
      })
    })
  }

  // 重置表单
  const resetFields = () => {
    if (formRef.value) {
      formRef.value.resetFields()
      formState.dirty = false
    }
  }

  // 设置表单数据 (确保深拷贝)
  const setForm = (data: Record<string, any>) => {
    // 如果弹窗未显示或表单未初始化，直接设置
    if (!dialog.visible.value || Object.keys(form.value).length === 0) {
      form.value = JSON.parse(JSON.stringify(data || {}))
      // 更新初始表单数据
      initialFormData.value = JSON.parse(JSON.stringify(data || {}))
      formState.dirty = false
      return
    }

    // 如果弹窗已显示但表单未修改，允许设置
    if (!formState.dirty) {
      form.value = JSON.parse(JSON.stringify(data || {}))
      formState.dirty = false
    }
  }

  // 提交表单
  const submitForm = async () => {
    if (formState.submitting) return false

    if (mergedOptions.validateOnSubmit) {
      try {
        formState.submitting = true
        submitLoading.value = true
        const valid = await validate()
        return valid ? form.value : false
      } catch (error) {
        return Promise.reject(error)
      } finally {
        formState.submitting = false
        submitLoading.value = false
      }
    } else {
      return form.value
    }
  }

  // 打开对话框
  const open = (formData?: Record<string, any>) => {
    if (formData) {
      setForm(formData)
    }
    dialog.open()
    formState.dirty = false
  }

  // 关闭对话框
  const close = () => {
    dialog.close()
  }

  // 监听表单变化
  watch(
    () => form.value,
    () => {
      formState.dirty = true
    },
    { deep: true }
  )

  // 监听对话框关闭
  watch(
    () => dialog.visible.value,
    (newVal, oldVal) => {
      // 只在对话框从显示变为不显示，且明确设置了resetOnClose时重置
      if (!newVal && oldVal && mergedOptions.resetOnClose) {
        // 延迟重置，确保关闭动画完成
        setTimeout(() => {
          resetFields()
          // 恢复初始状态
          form.value = JSON.parse(JSON.stringify(initialFormData.value || {}))
          formState.dirty = false
        }, 300)
      }
    }
  )

  return {
    ...dialog,
    form,
    formRef,
    formLoading,
    submitLoading,
    formState,
    validate,
    resetFields,
    setForm,
    submitForm,
    open,
    close,
  }
}
